Retrieve Rustc info lazily
authorAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 15 Jul 2016 17:14:34 +0000 (20:14 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 15 Jul 2016 17:19:11 +0000 (20:19 +0300)
src/cargo/ops/cargo_clean.rs
src/cargo/ops/cargo_compile.rs
src/cargo/ops/cargo_rustc/fingerprint.rs
src/cargo/ops/cargo_rustc/mod.rs
src/cargo/ops/cargo_test.rs
src/cargo/util/config.rs
tests/version.rs

index b205593376fe8cda5c2a10849bd68de64bb880af..2938e70cc7974bb4f875ece9f9924f1cdf6f0590 100644 (file)
@@ -33,9 +33,10 @@ pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> {
     let packages = ops::get_resolved_packages(&resolve, registry);
 
     let profiles = try!(ws.current()).manifest().profiles();
+    let host_triple = try!(opts.config.rustc_info()).host.clone();
     let mut cx = try!(Context::new(ws, &resolve, &packages, opts.config,
                                    BuildConfig {
-                                       host_triple: opts.config.rustc_info().host.clone(),
+                                       host_triple: host_triple,
                                        requested_target: opts.target.map(|s| s.to_owned()),
                                        release: opts.release,
                                        ..BuildConfig::default()
index 744cc54e9003547eb7020e7e9e842df7321f8e0c..17539c4d7ac48b9a17a7dc0e255730b70f0a034c 100644 (file)
@@ -443,7 +443,7 @@ fn scrape_build_config(config: &Config,
     let cfg_target = try!(config.get_string("build.target")).map(|s| s.val);
     let target = target.or(cfg_target);
     let mut base = ops::BuildConfig {
-        host_triple: config.rustc_info().host.clone(),
+        host_triple: try!(config.rustc_info()).host.clone(),
         requested_target: target.clone(),
         jobs: jobs,
         ..Default::default()
index 2bef5a90774a8cd8b43c72e82f463b42f69e5c27..d8b62319bf35935f1444036b56bf38adcdc9562e 100644 (file)
@@ -352,7 +352,7 @@ fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
         try!(cx.rustflags_args(unit))
     };
     let fingerprint = Arc::new(Fingerprint {
-        rustc: util::hash_u64(&cx.config.rustc_info().verbose_version),
+        rustc: util::hash_u64(&try!(cx.config.rustc_info()).verbose_version),
         target: util::hash_u64(&unit.target),
         profile: util::hash_u64(&unit.profile),
         features: format!("{:?}", features),
index 204d4d0adb3b6d2c7b1c2272a566c21451bc1238..76f9dc27f7c7c15cbe3c21ad8024453e1e758d02 100644 (file)
@@ -204,7 +204,7 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
 
     let name = unit.pkg.name().to_string();
     if !cx.show_warnings(unit.pkg.package_id()) {
-        if cx.config.rustc_info().cap_lints {
+        if try!(cx.config.rustc_info()).cap_lints {
             rustc.arg("--cap-lints").arg("allow");
         } else {
             rustc.arg("-Awarnings");
index 3e22a7e17b6e153a120965a15e751c42651e8578..5eb106b1e6f21a97219daede85997ea34c06ec51 100644 (file)
@@ -117,7 +117,7 @@ fn run_doc_tests(options: &TestOptions,
 
     // We don't build/rust doctests if target != host
     if let Some(target) = options.compile_opts.target {
-        if config.rustc_info().host != target {
+        if try!(config.rustc_info()).host != target {
             return Ok(errors);
         }
     }
index a89f010e85ac41c5a84c47a14a37c71cf25990dd..37bdf0357361ef5a67dc18cfa2b7b4fefbb46a8f 100644 (file)
@@ -24,7 +24,7 @@ use self::ConfigValue as CV;
 pub struct Config {
     home_path: Filesystem,
     shell: RefCell<MultiShell>,
-    rustc_info: Rustc,
+    rustc_info: RefCell<Option<Rustc>>,
     values: RefCell<HashMap<String, ConfigValue>>,
     values_loaded: Cell<bool>,
     cwd: PathBuf,
@@ -41,7 +41,7 @@ impl Config {
         let mut cfg = Config {
             home_path: Filesystem::new(homedir),
             shell: RefCell::new(shell),
-            rustc_info: Rustc::blank(),
+            rustc_info: RefCell::new(None),
             cwd: cwd,
             values: RefCell::new(HashMap::new()),
             values_loaded: Cell::new(false),
@@ -52,7 +52,6 @@ impl Config {
         };
 
         try!(cfg.scrape_tool_config());
-        try!(cfg.scrape_rustc_version());
         try!(cfg.scrape_target_dir_config());
 
         Ok(cfg)
@@ -100,7 +99,12 @@ impl Config {
 
     pub fn rustdoc(&self) -> &Path { &self.rustdoc }
 
-    pub fn rustc_info(&self) -> &Rustc { &self.rustc_info }
+    pub fn rustc_info(&self) -> CargoResult<Ref<Rustc>> {
+        if self.rustc_info.borrow().is_none() {
+            *self.rustc_info.borrow_mut() = Some(try!(Rustc::new(&self.rustc)));
+        }
+        Ok(Ref::map(self.rustc_info.borrow(), |opt| opt.as_ref().unwrap()))
+    }
 
     pub fn values(&self) -> CargoResult<Ref<HashMap<String, ConfigValue>>> {
         if !self.values_loaded.get() {
@@ -368,11 +372,6 @@ impl Config {
         Ok(())
     }
 
-    fn scrape_rustc_version(&mut self) -> CargoResult<()> {
-        self.rustc_info = try!(Rustc::new(&self.rustc));
-        Ok(())
-    }
-
     fn scrape_target_dir_config(&mut self) -> CargoResult<()> {
         if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
             *self.target_dir.borrow_mut() = Some(Filesystem::new(self.cwd.join(dir)));
index e8b38262a4743b77e9f5437eaed06dc6256bc4ce..f15f1e2cda4a469d5b8f2af61af0b3d739c3096d 100644 (file)
@@ -49,3 +49,10 @@ Options:
                 usage, &args, false);
     assert_eq!(result.unwrap(), Some("foo <version>".to_string()));
 }
+
+#[test]
+fn version_works_without_rustc() {
+    let p = project("foo");
+    assert_that(p.cargo_process("version").env("PATH", ""),
+                execs().with_status(0));
+}
\ No newline at end of file